---
title: Example
sidebar_label: Example
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import useBaseUrl from '@docusaurus/useBaseUrl';

Let's create a simple todo-item graphql example.

## Set up a new nest app

```sh
npm i -g @nestjs/cli
nest new nestjs-query-getting-started
```

## Install Dependencies

[Install your packages](./install.md).

:::note
Be sure to install the correct ORM package!
:::

Install extra dependencies for the example.
```sh
npm i pg apollo-server-express
```

## Generate the Module

From the root of your project run:

```sh
npx nest g mo todo-item
```

## Create the Entity

From the root of your project run:

```sh
npx nest g cl todo-item.entity todo-item
```

Now lets fill out the entity.

Add the following to `src/todo-item/todo-item.entity.ts`.

<Tabs
  defaultValue="typeorm"
  groupId="orm"
  values={[
    { label: 'TypeOrm', value: 'typeorm', },
    { label: 'Sequelize', value: 'sequelize', },
    { label: 'Mongoose', value: 'mongoose', },
    { label: 'Typegoose', value: 'typegoose', },
  ]
}>
<TabItem value="typeorm">

```ts title="todo-item/todo-item.entity.ts"
import {
  Column,
  CreateDateColumn,
  Entity,
  PrimaryGeneratedColumn,
  UpdateDateColumn,
} from 'typeorm';

@Entity()
export class TodoItemEntity {
  @PrimaryGeneratedColumn()
  id!: string;

  @Column()
  title!: string;

  @Column()
  completed!: boolean;

  @CreateDateColumn()
  created!: Date;

  @UpdateDateColumn()
  updated!: Date;
}
```

</TabItem>
<TabItem value="sequelize">

```ts title="todo-item/todo-item.entity.ts"
import {
  Table,
  Column,
  Model,
  CreatedAt,
  UpdatedAt,
  PrimaryKey,
  AutoIncrement,
} from 'sequelize-typescript';

@Table
export class TodoItemEntity extends Model<TodoItemEntity, Partial<TodoItemEntity>> {
  @PrimaryKey
  @AutoIncrement
  @Column
  id!: number;

  @Column
  title!: string;

  @Column
  completed!: boolean;

  @CreatedAt
  created!: Date;

  @UpdatedAt
  updated!: Date;
}

```

</TabItem>
<TabItem value="mongoose">

```ts title="todo-item/todo-item.entity.ts"
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';

@Schema({ timestamps: { createdAt: 'created', updatedAt: 'updated' } })
export class TodoItemEntity extends Document {
  @Prop({ required: true })
  title!: string;

  @Prop()
  description?: string;

  @Prop({ required: true })
  completed!: boolean;

  @Prop({ default: Date.now })
  created!: Date;

  @Prop({ default: Date.now })
  updated!: Date;
}

export const TodoItemEntitySchema = SchemaFactory.createForClass(TodoItemEntity);

```

</TabItem>
<TabItem value="typegoose">

```ts title="todo-item/todo-item.entity.ts"
import { Base } from '@typegoose/typegoose/lib/defaultClasses';
import { Prop, modelOptions, Ref } from '@typegoose/typegoose';
import { Types } from 'mongoose';
import { SubTaskEntity } from '../sub-task/sub-task.entity';
import { TagEntity } from '../tag/tag.entity';

@modelOptions({
  schemaOptions: {
    timestamps: { createdAt: 'created', updatedAt: 'updated' },
    collection: 'todo-items',
    toObject: { virtuals: true },
  },
})
export class TodoItemEntity implements Base {
  @Prop({ required: true })
  title!: string;

  @Prop()
  description?: string;

  @Prop({ required: true })
  completed!: boolean;

  @Prop({ default: Date.now })
  created!: Date;

  @Prop({ default: Date.now })
  updated!: Date;
}
```

</TabItem>
</Tabs>

## Create the DTO

The DTO (Data Transfer Object) is used by the resolver to represent incoming requests and outgoing responses.

The DTO is where you can:

* Define fields that should be rendered by graphql.
* Define fields that should be filterable using the `@FilterableField` decorator.
* Define validation that will be used by mutations.

In this example the DTO and entity are two different classes to clearly demonstrate what is required for `graphql` vs
the persistence layer. However, you can combine the two into a single class.

From the root of your project run:
```sh
npx nest g cl todo-item.dto todo-item
```

Now lets fill out the DTO. Add the following to `src/todo-item/todo-item.dto.ts`.

```ts title="todo-item/todo-item.dto.ts"
import { FilterableField, IDField } from '@nestjs-query/query-graphql';
import { ObjectType, GraphQLISODateTime, Field, ID } from '@nestjs/graphql';

@ObjectType('TodoItem')
export class TodoItemDTO {
  @IDField(() => ID)
  id!: number;

  @FilterableField()
  title!: string;

  @FilterableField()
  completed!: boolean;

  @Field(() => GraphQLISODateTime)
  created!: Date;

  @Field(() => GraphQLISODateTime)
  updated!: Date;
}


```

Notice the use of `@FilterableField` this will let `@nestjs-query/query-graphql` know to allow filtering on the
corresponding field. If you just use `@Field` then you will not be able to filter on the corresponding field.

## Wire everything up.

Update the `todo-item.module` to set up the `NestjsQueryGraphQLModule` and the entities to provide a `QueryService`.

The `NestjsQueryGraphQLModule` will automatically create a Resolver that will expose the following `queries` and `mutations`:

**Queries**

* `todoItems` - find multiple `TodoItem`s.
* `todoItem` - find one `TodoItem`.

**Mutations**

* `createManyTodoItems` - create multiple `TodoItem`s.
* `createOneTodoItems` - create one `TodoItem`.
* `updateManyTodoItems` - update multiple `TodoItems`.
* `updateOneTodoItems` - update one `TodoItem`.
* `deleteManyTodoItems` - delete multiple `TodoItems`s.
* `deleteOneTodoItems` - delete one `TodoItem`.

<Tabs
  defaultValue="typeorm"
  groupId="orm"
  values={[
    { label: 'TypeOrm', value: 'typeorm', },
    { label: 'Sequelize', value: 'sequelize', },
    { label: 'Mongoose', value: 'mongoose', },
    { label: 'Typegoose', value: 'typegoose', },
  ]
}>
<TabItem value="typeorm">

```ts {9-15}
import { NestjsQueryGraphQLModule } from '@nestjs-query/query-graphql';
import { NestjsQueryTypeOrmModule } from '@nestjs-query/query-typeorm';
import { Module } from '@nestjs/common';
import { TodoItemDTO } from './todo-item.dto';
import { TodoItemEntity } from './todo-item.entity';

@Module({
  imports: [
    NestjsQueryGraphQLModule.forFeature({
      // import the NestjsQueryTypeOrmModule to register the entity with typeorm
      // and provide a QueryService
      imports: [NestjsQueryTypeOrmModule.forFeature([TodoItemEntity])],
      // describe the resolvers you want to expose
      resolvers: [{ DTOClass: TodoItemDTO, EntityClass: TodoItemEntity }],
    }),
  ],
})
export class TodoItemModule {}
```

</TabItem>
<TabItem value="sequelize">

```ts {9-15}
import { NestjsQueryGraphQLModule } from '@nestjs-query/query-graphql';
import { NestjsQuerySequelizeModule } from '@nestjs-query/query-sequelize';
import { Module } from '@nestjs/common';
import { TodoItemDTO } from './todo-item.dto';
import { TodoItemEntity } from './todo-item.entity';

@Module({
  imports: [
    NestjsQueryGraphQLModule.forFeature({
      // import the NestjsQuerySequelizeModule to register the entity with sequelize
      // and provide a QueryService
      imports: [NestjsQuerySequelizeModule.forFeature([TodoItemEntity])],
      // describe the resolvers you want to expose
      resolvers: [{ DTOClass: TodoItemDTO, EntityClass: TodoItemEntity }],
    }),
  ],
})
export class TodoItemModule {}
```

</TabItem>
<TabItem value="mongoose">

```ts {9-19}
import { NestjsQueryGraphQLModule } from '@nestjs-query/query-graphql';
import { NestjsQueryMongooseModule } from '@nestjs-query/query-mongoose';
import { Module } from '@nestjs/common';
import { TodoItemDTO } from './todo-item.dto';
import { TodoItemEntity, TodoItemEntitySchema } from './todo-item.entity';

@Module({
  imports: [
    NestjsQueryGraphQLModule.forFeature({
      // import the NestjsQueryMongooseModule to register the entity with mongoose
      // and provide a QueryService
      imports: [
        NestjsQueryMongooseModule.forFeature([
          { document: TodoItemEntity, name: TodoItemEntity.name, schema: TodoItemEntitySchema },
        ]),
      ],
      // describe the resolvers you want to expose
      resolvers: [{ DTOClass: TodoItemDTO, EntityClass: TodoItemEntity }],
    }),
  ],
})
export class TodoItemModule {}
```

</TabItem>
<TabItem value="typegoose">

```ts {9-19}
import { NestjsQueryGraphQLModule } from '@nestjs-query/query-graphql';
import { Module } from '@nestjs/common';
import { NestjsQueryTypegooseModule } from '@nestjs-query/query-typegoose';
import { TodoItemDTO } from './dto/todo-item.dto';
import { TodoItemEntity } from './todo-item.entity';

const guards = [AuthGuard];
@Module({
  providers: [TodoItemResolver],
  imports: [
    NestjsQueryGraphQLModule.forFeature({
      imports: [NestjsQueryTypegooseModule.forFeature([TodoItemEntity])],
      resolvers: [{ DTOClass: TodoItemDTO, EntityClass: TodoItemEntity }],
    }),
  ],
})
export class TodoItemModule {}
```

</TabItem>
</Tabs>

Next update `app.module` to set up your db connection and the `graphql` nest modules.


<Tabs
  defaultValue="typeorm"
  groupId="orm"
  values={[
    { label: 'TypeOrm', value: 'typeorm', },
    { label: 'Sequelize', value: 'sequelize', },
    { label: 'Mongoose', value: 'mongoose', },
    { label: 'Typegoose', value: 'typegoose', },
  ]
}>
<TabItem value="typeorm">

```ts
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TodoItemModule } from './todo-item/todo-item.module';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'postgres',
      database: 'gettingstarted',
      username: 'gettingstarted',
      autoLoadEntities: true,
      synchronize: true,
      logging: true,
    }),
    GraphQLModule.forRoot({
      // set to true to automatically generate schema
      autoSchemaFile: true,
    }),
    TodoItemModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

</TabItem>
<TabItem value="sequelize">

```ts
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { SequelizeModule } from '@nestjs/sequelize';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TodoItemModule } from './todo-item/todo-item.module';

@Module({
  imports: [
    TodoItemModule,
    SequelizeModule.forRoot({
      dialect: 'postgres',
      database: 'gettingstarted',
      username: 'gettingstarted',
      autoLoadModels: true,
      synchronize: true,
      logging: true,
    }),
    GraphQLModule.forRoot({
      // set to true to automatically generate schema
      autoSchemaFile: true,
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}


```

</TabItem>
<TabItem value="mongoose">

```ts
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { MongooseModule } from '@nestjs/mongoose';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TodoItemModule } from './todo-item/todo-item.module';

@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost/nest', options),
    GraphQLModule.forRoot({
      // set to true to automatically generate schema
      autoSchemaFile: true,
    }),
    TodoItemModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}


```

</TabItem>
<TabItem value="typegoose">

```ts
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { TypegooseModule } from 'nestjs-typegoose';
import { TodoItemModule } from './todo-item/todo-item.module';

@Module({
  imports: [
    TypegooseModule.forRoot('mongodb://localhost/nest', options),
    GraphQLModule.forRoot({
      // set to true to automatically generate schema
      autoSchemaFile: true,
    }),
    TodoItemModule,
  ],
})
export class AppModule {}


```
**NOTE** For the sake of brevity, the `options` object in the Mongoose and Typegoose examples aren't defined. If you'd like to see full examples of all of the persistence services, please refer to the `./examples` directory in the [source code](https://github.com/doug-martin/nestjs-query/tree/master/examples).

</TabItem>
</Tabs>

Create a `docker-compose.yml` file in the root of the project

```dockerfile
version: "3"

services:
  postgres:
    image: "postgres:11.5"
    environment:
      - "POSTGRES_USER=gettingstarted"
      - "POSTGRES_DB=gettingstarted"
    expose:
      - "5432"
    ports:
      - "5432:5432"
  # only needed if using mongoose
  mongo:
    image: "mongo:4.4"
    restart: always
    ports:
      - "27017:27017"
  mongo-express:
    image: "mongo-express:latest"
    restart: always
    ports:
      - 8081:8081


```

## Running the Example

Start the backing services
```sh
docker-compose up -d
```

Start the app

```sh
npm start
```

Visit http://localhost:3000/graphql where you should see the playground

<img alt="Example playground" src={useBaseUrl('img/introduction/getting-started-playground.png')} />

## Exploring The GraphQL Endpoint

### Create a TodoItem

<Tabs
  defaultValue="graphql"
  values={[
    { label: 'GraphQL', value: 'graphql', },
    { label: 'Response', value: 'response', },
  ]
}>
<TabItem value="graphql">

```graphql
mutation {
  createOneTodoItem(
    input: { todoItem: { title: "Create One Todo Item", completed: false } }
  ) {
    id
    title
    completed
    created
    updated
  }
}
```

</TabItem>
<TabItem value="response">

```json
{
  "data": {
    "createOneTodoItem": {
      "id": "1",
      "title": "Create One Todo Item",
      "completed": false,
      "created": "2020-01-01T00:43:16.000Z",
      "updated": "2020-01-01T00:43:16.000Z"
    }
  }
}
```

</TabItem>
</Tabs>

### Create Multiple TodoItems

<Tabs
  defaultValue="graphql"
  values={[
    { label: 'GraphQL', value: 'graphql', },
    { label: 'Response', value: 'response', },
  ]
}>
<TabItem value="graphql">

```graphql
mutation {
  createManyTodoItems(
    input: {
      todoItems: [
        { title: "Create Many Todo Items - 1", completed: false }
        { title: "Create Many Todo Items - 2", completed: true }
      ]
    }
  ) {
    id
    title
    completed
    created
    updated
  }
}
```

</TabItem>
<TabItem value="response">

```json
{
  "data": {
    "createManyTodoItems": [
      {
        "id": "2",
        "title": "Create Many Todo Items - 1",
        "completed": false,
        "created": "2020-01-01T00:49:01.000Z",
        "updated": "2020-01-01T00:49:01.000Z"
      },
      {
        "id": "3",
        "title": "Create Many Todo Items - 2",
        "completed": true,
        "created": "2020-01-01T00:49:01.000Z",
        "updated": "2020-01-01T00:49:01.000Z"
      }
    ]
  }
}
```

</TabItem>
</Tabs>

### Query For Multiple TodoItems

#### Query for all todo items

<Tabs
  defaultValue="graphql"
  values={[
    { label: 'GraphQL', value: 'graphql', },
    { label: 'Response', value: 'response', },
  ]
}>
<TabItem value="graphql">

```graphql
{
  todoItems {
    pageInfo {
      hasNextPage
      hasPreviousPage
      startCursor
      endCursor
    }
    edges {
      node {
        id
        title
        completed
        created
        updated
      }
      cursor
    }
  }
}
```


</TabItem>
<TabItem value="response">


```json
{
  "data": {
    "todoItems": {
      "pageInfo": {
        "hasNextPage": false,
        "hasPreviousPage": false,
        "startCursor": "YXJyYXljb25uZWN0aW9uOjA=",
        "endCursor": "YXJyYXljb25uZWN0aW9uOjI="
      },
      "edges": [
        {
          "node": {
            "id": "1",
            "title": "Create One Todo Item",
            "completed": false,
            "created": "2020-01-01T00:43:16.000Z",
            "updated": "2020-01-01T00:43:16.000Z"
          },
          "cursor": "YXJyYXljb25uZWN0aW9uOjA="
        },
        {
          "node": {
            "id": "2",
            "title": "Create Many Todo Items - 1",
            "completed": false,
            "created": "2020-01-01T00:49:01.000Z",
            "updated": "2020-01-01T00:49:01.000Z"
          },
          "cursor": "YXJyYXljb25uZWN0aW9uOjE="
        },
        {
          "node": {
            "id": "3",
            "title": "Create Many Todo Items - 2",
            "completed": true,
            "created": "2020-01-01T00:49:01.000Z",
            "updated": "2020-01-01T00:49:01.000Z"
          },
          "cursor": "YXJyYXljb25uZWN0aW9uOjI="
        }
      ]
    }
  }
}
```

</TabItem>
</Tabs>

#### Query for completed todo items

<Tabs
  defaultValue="graphql"
  values={[
    { label: 'GraphQL', value: 'graphql', },
    { label: 'Response', value: 'response', },
  ]
}>
<TabItem value="graphql">

```graphql
{
  todoItems(filter: { completed: { is: true } }) {
    pageInfo {
      hasNextPage
      hasPreviousPage
      startCursor
      endCursor
    }
    edges {
      node {
        id
        title
        completed
        created
        updated
      }
      cursor
    }
  }
}
```

</TabItem>
<TabItem value="response">

```json
{
  "data": {
    "todoItems": {
      "pageInfo": {
        "hasNextPage": false,
        "hasPreviousPage": false,
        "startCursor": "YXJyYXljb25uZWN0aW9uOjA=",
        "endCursor": "YXJyYXljb25uZWN0aW9uOjA="
      },
      "edges": [
        {
          "node": {
            "id": "3",
            "title": "Create Many Todo Items - 2",
            "completed": true,
            "created": "2020-01-01T00:49:01.000Z",
            "updated": "2020-01-01T00:49:01.000Z"
          },
          "cursor": "YXJyYXljb25uZWN0aW9uOjA="
        }
      ]
    }
  }
}
```

</TabItem>
</Tabs>

### Query For One TodoItem

#### Query by id

<Tabs
  defaultValue="graphql"
  values={[
    { label: 'GraphQL', value: 'graphql', },
    { label: 'Response', value: 'response', },
  ]
}>
<TabItem value="graphql">

```graphql
{
  todoItem(id: 1) {
    id
    title
    completed
    created
    updated
  }
}
```

</TabItem>
<TabItem value="response">


```json
{
  "data": {
    "todoItem": {
      "id": "1",
      "title": "Create One Todo Item",
      "completed": false,
      "created": "2020-01-13T06:19:17.543Z",
      "updated": "2020-01-13T06:19:17.543Z"
    }
  }
}
```

</TabItem>
</Tabs>


### Update a TodoItem

Lets update the completed `TodoItem` we created earlier to not be completed.
<Tabs
  defaultValue="graphql"
  values={[
    { label: 'GraphQL', value: 'graphql', },
    { label: 'Response', value: 'response', },
  ]
}>
<TabItem value="graphql">

```graphql
mutation {
  updateOneTodoItem(input: { id: 3, update: { completed: false } }) {
    id
    title
    completed
    created
    updated
  }
}
```

</TabItem>
<TabItem value="response">

```json
{
  "data": {
    "updateOneTodoItem": {
      "id": "3",
      "title": "Create Many Todo Items - 2",
      "completed": false,
      "created": "2020-01-13T09:19:46.727Z",
      "updated": "2020-01-13T09:23:37.658Z"
    }
  }
}
```

</TabItem>
</Tabs>

### Update Multiple TodoItems

Lets update the completed `TodoItem` we created earlier to not be completed.
<Tabs
  defaultValue="graphql"
  values={[
    { label: 'GraphQL', value: 'graphql', },
    { label: 'Response', value: 'response', },
  ]
}>
<TabItem value="graphql">

```graphql
mutation {
  updateManyTodoItems(
    input: { filter: { id: { in: [1, 2] } }, update: { completed: true } }
  ) {
    updatedCount
  }
}

```

</TabItem>
<TabItem value="response">

```json
{
  "data": {
    "updateManyTodoItems": {
      "updatedCount": 2
    }
  }
}
```

</TabItem>
</Tabs>

You can check this by running the completed query from above.


### Delete One TodoItem

Lets update delete the first `TodoItem`.
<Tabs
  defaultValue="graphql"
  values={[
    { label: 'GraphQL', value: 'graphql', },
    { label: 'Response', value: 'response', },
  ]
}>
<TabItem value="graphql">

```graphql
mutation {
  deleteOneTodoItem(input: { id: 1 }) {
    id
    title
    completed
    created
    updated
  }
}
```

</TabItem>
<TabItem value="response">

```json
{
  "data": {
    "deleteOneTodoItem": {
      "id": null,
      "title": "Create One Todo Item",
      "completed": true,
      "created": "2020-01-13T09:44:41.176Z",
      "updated": "2020-01-13T09:44:54.822Z"
    }
  }
}
```

</TabItem>
</Tabs>

### Delete Many TodoItems

Lets update delete the create many todo items `TodoItem` using a filter.

<Tabs
  defaultValue="graphql"
  values={[
    { label: 'GraphQL', value: 'graphql', },
    { label: 'Response', value: 'response', },
  ]
}>
<TabItem value="graphql">

```graphql
mutation {
  deleteManyTodoItems(
    input: { filter: { title: { like: "Create Many Todo Items%" } } }
  ) {
    deletedCount
  }
}
```

</TabItem>
<TabItem value="response">

```json
{
  "data": {
    "deleteManyTodoItems": {
      "deletedCount": 2
    }
  }
}
```

</TabItem>
</Tabs>

